package com.wlz.creational.singleton.lazy;

import java.io.Serializable;

/**
 * @author： wlz
 * @Date 2020/7/21 10:04
 * @description： TODO
 * @version: 1.0
 * 懒汉式:
 *      该懒汉式写法也被称为：Double Check（双重校验） + Lock（加锁）
 * 创建一个对象：
 *      1.为 singleton 分配内存空间
 *      2.初始化 singleton 对象
 *      3.将 singleton 指向分配好的内存空间
 * 指令重排序是指：JVM 在保证最终结果正确的情况下，可以不按照程序编码的顺序执行语句，尽可能提高程序的性能
 */
public class LazySingleton implements Serializable {

    private static final long serialVersionUID = 1L;

    // 加volatile 防止指令重排
    private static volatile LazySingleton singleton;

    private LazySingleton(){}

    public static LazySingleton getInstance() {
        // 线程A和线程B同时看到singleton = null，如果不为null，则直接返回singleton
        if (singleton == null) {
            // 线程A或线程B获得该锁进行初始化
            synchronized(LazySingleton.class) {
                if (singleton == null) { // 其中一个线程进入该分支，另外一个线程则不会进入该分支
                    singleton = new LazySingleton();
                }
            }
        }
        return singleton;
    }



}
